﻿using Himp.Base;
using Himp.Platform;
using Microsoft.AspNetCore.Authorization;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Identity;
using Volo.Abp.ObjectMapping;
using Volo.Abp.TenantManagement;

namespace Ocean.His.Main
{
    /// <summary>
    /// 机构信息服务
    /// </summary>
    public class OrganService : PlatformAppService
    {
        private readonly IRepository<Organ, Guid> _organRepository;
        private readonly IRepository<OrganGrant, Guid> _organGrantRepository;
        private IBizSeqService _bizSeqService;
        private readonly OrganManager _organManager;
        private readonly IIdentityUserAppService _identityUserAppService;
        private ITenantAppService _tenantAppService;

        public OrganService(IRepository<Organ, Guid> organInfoRepository
            , IRepository<OrganGrant, Guid> organGrantRepository
            , IBizSeqService bizSeqService
            , OrganManager organManager
            , IIdentityUserAppService identityUserAppService
            , ITenantAppService tenantAppService)
        {
            _organRepository = organInfoRepository;
            _organGrantRepository = organGrantRepository;
            _bizSeqService = bizSeqService;
            _organManager = organManager;
            _identityUserAppService = identityUserAppService;
            _tenantAppService = tenantAppService;
        }

        /// <summary>
        /// 获取全部机构信息
        /// </summary>
        /// <returns></returns>
        public async Task<PagedResultDto<OrganDto>> GetListAsync(OrganInput input)
        {
            var iQuery = await _organRepository.GetQueryableAsync();
            iQuery = iQuery.WhereIf(!string.IsNullOrEmpty(input.Filter), i => i.OrganName.Contains(input.Filter));

            if (input.Pi == 0)
            {
                var itemsDto = ObjectMapper.Map<List<Organ>, List<OrganDto>>(iQuery.ToList());

                return new PagedResultDto<OrganDto>(itemsDto.Count, itemsDto);
            }
            else
            {
                var totalCount = iQuery.Count();
                var items = iQuery.Page(input.Pi, input.Ps);
                var itemsDto = ObjectMapper.Map<List<Organ>, List<OrganDto>>(items.ToList());

                return new PagedResultDto<OrganDto>(totalCount, itemsDto);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public async Task<OrganDto> GetAsync(Guid id)
        {
            var organInfo = await _organRepository.GetAsync(id);
            var itemDto = ObjectMapper.Map<Organ, OrganDto>(organInfo);

            return itemDto;
        }

        /// <summary>
        /// 申请用户机构信息
        /// </summary>
        /// <returns></returns>
        public async Task<OrganDto> PostAsync(OrganCreateDto input)
        {
            var organCode = await _bizSeqService.GetAsync("机构");
            Organ organInfo = _organManager.CreateOrganInfo(organCode, input.OrganName, input.AdminTel
                , input.AdminEmail, input.AdminPwd);
            organInfo = await _organRepository.InsertAsync(organInfo);
            var organDto = ObjectMapper.Map<Organ, OrganDto>(organInfo);

            return organDto;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="id"></param>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<OrganDto> PutAsync(Guid id, OrganUpdateDto input)
        {
            var organInfo = await _organRepository.GetAsync(id);
            organInfo = ObjectMapper.Map(input, organInfo);
            var itemDto = ObjectMapper.Map<Organ, OrganDto>(organInfo);

            return itemDto;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task DeleteAsync(Guid id)
        { 
            await _organRepository.DeleteAsync(id);
        }

        /// <summary>
        /// 创建机构信息同时生成租户
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<OrganDto> PutReviewAsync(Guid id)
        {
            var organ = await _organRepository.GetAsync(id);

            #region 创建租户

            TenantCreateDto tenantCreateDto = new TenantCreateDto();
            tenantCreateDto.Name = organ.OrganName;
            tenantCreateDto.AdminEmailAddress = organ.AdminEmail;
            tenantCreateDto.AdminPassword = organ.AdminPwd;
            var tenant = await _tenantAppService.CreateAsync(tenantCreateDto);

            #endregion

            #region 更新组织信息

            organ.OrganStatus = EnumOrganStatus.审核通过;
            organ.TenantId = tenant.Id;
            organ.Endtime = DateTime.Now.AddMonths(3);

            #endregion

            #region 创建用户

            string defaultRole = "admin";
            IdentityUserCreateDto identityUserCreateDto = new IdentityUserCreateDto();
            identityUserCreateDto.Password = organ.AdminPwd;
            identityUserCreateDto.UserName = organ.AdminTel;
            identityUserCreateDto.Name = organ.AdminName;
            identityUserCreateDto.Email = organ.AdminEmail;
            identityUserCreateDto.PhoneNumber = organ.AdminTel;
            identityUserCreateDto.RoleNames = new string[] { defaultRole };
            identityUserCreateDto.IsActive = true;
            identityUserCreateDto.LockoutEnabled = true;
            var user = await _identityUserAppService.CreateAsync(identityUserCreateDto);

            #endregion

            #region 创建租户账户对应组织关系

            OrganGrant organGrant = new OrganGrant();
            organGrant.ProviderKey = "U";
            organGrant.ProviderName = user.Id.ToString();
            organGrant.OrganId = id;
            organGrant = await _organGrantRepository.InsertAsync(organGrant);

            //UserAsOrgan userAsOrgan = new UserAsOrgan();
            //userAsOrgan.UserName = identityUserCreateDto.UserName;
            //userAsOrgan.OrganId = organ.Id;
            //userAsOrgan.TenantId = tenant.Id;
            //await _userAsOrganRepository.InsertAsync(userAsOrgan);

            #endregion

            var organDto = ObjectMapper.Map<Organ, OrganDto>(organ);

            return organDto;
        }
    }
}
